"""
项目相关数据模型
"""
from datetime import datetime, date
from typing import List, Optional, Dict, Any
from enum import Enum
from pydantic import BaseModel, Field, validator, field_validator
from bson import ObjectId
from app.models.base import PyObjectId

# 项目状态通过state模块进行管理，使用字符串类型
# 使用 app.utils.state_utils 或 app.services.state_service 获取动态状态

class ProjectPriority(str, Enum):
    """项目优先级"""
    LOW = "low"           # 低
    MEDIUM = "medium"     # 中
    HIGH = "high"         # 高
    URGENT = "urgent"     # 紧急

class ProjectCategory(str, Enum):
    """项目分类"""
    WEB_DEVELOPMENT = "web_development"
    MOBILE_APP = "mobile_app"
    DESKTOP_APP = "desktop_app"
    API_DEVELOPMENT = "api_development"
    DATA_ANALYSIS = "data_analysis"
    MACHINE_LEARNING = "machine_learning"
    INFRASTRUCTURE = "infrastructure"
    TESTING = "testing"
    MAINTENANCE = "maintenance"
    RESEARCH = "research"
    OTHER = "other"

class ProjectMemberRole(str, Enum):
    """项目成员角色"""
    OWNER = "owner"           # 项目负责人
    MANAGER = "manager"       # 项目经理
    DEVELOPER = "developer"   # 开发人员
    TESTER = "tester"         # 测试人员
    DESIGNER = "designer"     # 设计师
    ANALYST = "analyst"       # 分析师
    VIEWER = "viewer"         # 查看者

class ProjectMember(BaseModel):
    """项目成员"""
    user_id: PyObjectId = Field(..., description="用户ID")
    roles: List[str] = Field(default_factory=list, description="项目角色ID列表")
    joined_at: datetime = Field(default_factory=datetime.utcnow, description="加入时间")
    permissions: List[str] = Field(default_factory=list, description="项目权限")

class ProjectBase(BaseModel):
    """项目基础模型"""
    name: str = Field(..., min_length=1, max_length=200, description="项目名称")
    description: Optional[str] = Field(None, max_length=2000, description="项目描述")
    category: ProjectCategory = Field(..., description="项目分类")
    priority: str = Field(default="medium", description="项目优先级")
    status: str = Field(default="", description="项目状态（从状态管理系统动态获取，创建时使用默认状态）")
    start_date: Optional[date] = Field(None, description="开始日期")
    end_date: Optional[date] = Field(None, description="结束日期")
    estimated_hours: Optional[int] = Field(None, ge=0, description="预估工时")
    budget: Optional[float] = Field(None, ge=0, description="项目预算")
    tags: List[str] = Field(default_factory=list, description="项目标签")
    is_public: bool = Field(default=False, description="是否公开")
    organization_id: Optional[PyObjectId] = Field(None, description="所属组织ID")
    
    @field_validator('priority', mode='before')
    @classmethod
    def validate_priority(cls, v):
        """允许动态优先级值，如果不在枚举中则作为字符串处理"""
        if isinstance(v, ProjectPriority):
            return v.value
        if isinstance(v, str):
            return v
        return str(v) if v else "medium"
    
    @validator('end_date')
    def validate_end_date(cls, v, values):
        if v and 'start_date' in values and values['start_date']:
            if v <= values['start_date']:
                raise ValueError('End date must be after start date')
        return v

class ProjectCreate(ProjectBase):
    """创建项目模型"""
    owner_id: Optional[str] = Field(None, description="项目负责人ID")
    members: List[ProjectMember] = Field(default_factory=list, description="项目成员")

class ProjectUpdate(BaseModel):
    """更新项目模型"""
    name: Optional[str] = Field(None, min_length=1, max_length=200, description="项目名称")
    description: Optional[str] = Field(None, max_length=2000, description="项目描述")
    category: Optional[ProjectCategory] = Field(None, description="项目分类")
    priority: Optional[str] = Field(None, description="项目优先级")
    status: Optional[str] = Field(None, description="项目状态")
    start_date: Optional[date] = Field(None, description="开始日期")
    end_date: Optional[date] = Field(None, description="结束日期")
    estimated_hours: Optional[int] = Field(None, ge=0, description="预估工时")
    budget: Optional[float] = Field(None, ge=0, description="项目预算")
    tags: Optional[List[str]] = Field(None, description="项目标签")
    is_public: Optional[bool] = Field(None, description="是否公开")
    owner_id: Optional[str] = Field(None, description="项目负责人ID")
    
    @field_validator('priority', mode='before')
    @classmethod
    def validate_priority(cls, v):
        """允许动态优先级值，如果不在枚举中则作为字符串处理"""
        if v is None:
            return None
        if isinstance(v, ProjectPriority):
            return v.value
        if isinstance(v, str):
            return v
        return str(v)
    
    @validator('end_date')
    def validate_end_date(cls, v, values):
        if v and 'start_date' in values and values['start_date']:
            if v <= values['start_date']:
                raise ValueError('End date must be after start date')
        return v

class ProjectInDB(ProjectBase):
    """数据库中的项目模型"""
    id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
    members: List[ProjectMember] = Field(default_factory=list, description="项目成员")
    created_by: PyObjectId = Field(..., description="创建者ID")
    created_at: datetime = Field(default_factory=datetime.utcnow, description="创建时间")
    updated_at: datetime = Field(default_factory=datetime.utcnow, description="更新时间")
    is_archived: bool = Field(default=False, description="是否已归档")
    
    class Config:
        populate_by_name = True
        arbitrary_types_allowed = True
        json_encoders = {ObjectId: str}

class Project(ProjectInDB):
    """项目响应模型"""
    pass

class ProjectResponse(BaseModel):
    """项目响应模型"""
    id: str = Field(..., description="项目ID")
    name: str = Field(..., description="项目名称")
    description: Optional[str] = Field(None, description="项目描述")
    category: ProjectCategory = Field(..., description="项目分类")
    priority: str = Field(..., description="项目优先级")
    status: str = Field(..., description="项目状态")
    start_date: Optional[date] = Field(None, description="开始日期")
    end_date: Optional[date] = Field(None, description="结束日期")
    estimated_hours: Optional[int] = Field(None, description="预估工时")
    budget: Optional[float] = Field(None, description="项目预算")
    tags: List[str] = Field(default_factory=list, description="项目标签")
    is_public: bool = Field(..., description="是否公开")
    organization_id: Optional[str] = Field(None, description="所属组织ID")
    members: List[ProjectMember] = Field(default_factory=list, description="项目成员")
    created_by: str = Field(..., description="创建者ID")
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")
    is_archived: bool = Field(..., description="是否已归档")
    owner_id: Optional[str] = Field(None, description="项目负责人ID")
    
    # 统计信息
    task_count: Optional[int] = Field(None, description="任务总数")
    completed_task_count: Optional[int] = Field(None, description="已完成任务数")
    member_count: Optional[int] = Field(None, description="成员数量")
    progress: Optional[float] = Field(None, description="项目进度百分比")

class ProjectSummary(BaseModel):
    """项目摘要模型"""
    id: str = Field(..., description="项目ID")
    name: str = Field(..., description="项目名称")
    status: str = Field(..., description="项目状态")
    priority: str = Field(..., description="项目优先级")
    progress: Optional[float] = Field(None, description="项目进度百分比")
    member_count: int = Field(..., description="成员数量")
    task_count: int = Field(..., description="任务总数")
    created_at: datetime = Field(..., description="创建时间")

class ProjectMemberUpdate(BaseModel):
    """更新项目成员模型"""
    roles: Optional[List[str]] = Field(None, description="项目角色ID列表")
    permissions: Optional[List[str]] = Field(None, description="项目权限")

class ProjectMemberAdd(BaseModel):
    """添加项目成员模型"""
    user_id: str = Field(..., description="用户ID")
    roles: List[str] = Field(..., description="项目角色ID列表")
    permissions: List[str] = Field(default_factory=list, description="项目权限")

class ProjectStats(BaseModel):
    """项目统计模型"""
    total_projects: int = Field(..., description="项目总数")
    active_projects: int = Field(..., description="活跃项目数")
    completed_projects: int = Field(..., description="已完成项目数")
    overdue_projects: int = Field(..., description="逾期项目数")
    projects_by_status: Dict[str, int] = Field(..., description="按状态分组的项目数")
    projects_by_priority: Dict[str, int] = Field(..., description="按优先级分组的项目数")
    projects_by_category: Dict[str, int] = Field(..., description="按分类分组的项目数")

class ProjectActivity(BaseModel):
    """项目活动模型"""
    id: str = Field(..., description="活动ID")
    project_id: str = Field(..., description="项目ID")
    user_id: str = Field(..., description="用户ID")
    user_name: str = Field(..., description="用户名称")
    action: str = Field(..., description="操作类型")
    description: str = Field(..., description="操作描述")
    metadata: Dict[str, Any] = Field(default_factory=dict, description="元数据")
    created_at: datetime = Field(..., description="创建时间")

class ProjectFilter(BaseModel):
    """项目筛选模型"""
    status: Optional[List[str]] = Field(None, description="状态筛选")
    priority: Optional[List[str]] = Field(None, description="优先级筛选")
    category: Optional[List[ProjectCategory]] = Field(None, description="分类筛选")
    tags: Optional[List[str]] = Field(None, description="标签筛选")
    created_by: Optional[str] = Field(None, description="创建者筛选")
    member_id: Optional[str] = Field(None, description="成员筛选")
    organization_id: Optional[str] = Field(None, description="组织筛选")
    date_range: Optional[Dict[str, date]] = Field(None, description="日期范围筛选")
    is_archived: Optional[bool] = Field(None, description="是否归档筛选")
